package com.yanyeori.framework.core.util;

import com.yanyeori.framework.core.interfaces.InterfaceFunction;
import org.apache.commons.lang3.CharUtils;

import java.beans.Introspector;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;

/**
 * 字段相关工具
 *
 * @author chenkuan
 * @since 2020/10/30
 */
public class FieldUtil {
    /**
     * 获取lambda列字段名
     *
     * @param function FieldFunction
     * @return fieldName
     */
    public static <T, R> String getFieldName(InterfaceFunction<T, R> function) throws ReflectiveOperationException {
        Method method = function.getClass().getDeclaredMethod("writeReplace");
        if (!method.isAccessible()) {
            method.setAccessible(true);
        }
        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(function);
        String getMethodName = serializedLambda.getImplMethodName();
        //去除字段前的get、is
        if (getMethodName.startsWith("get")) {
            getMethodName = getMethodName.substring(3);
        } else if (getMethodName.startsWith("is")) {
            getMethodName = getMethodName.substring(2);
        }
        //首字母小写
        return Introspector.decapitalize(getMethodName);
    }

    /**
     * 字段命名转换：添加前后缀、去除前后缀、驼峰命名转下划线
     */
    public static String convertName(String name, String addPrefix, String removePrefix, String addSuffix, String removeSuffix, boolean camelCaseToUnderscore) {
        StringBuilder prefix = StringUtil.isNotEmpty(addPrefix) ? new StringBuilder(addPrefix) : new StringBuilder();
        StringBuilder suffix = StringUtil.isNotEmpty(addSuffix) ? new StringBuilder(addSuffix) : new StringBuilder();
        if (StringUtil.isNotEmpty(removePrefix) && name.startsWith(removePrefix)) {
            name = name.substring(removePrefix.length());
        }
        if (StringUtil.isNotEmpty(removeSuffix) && name.endsWith(removeSuffix)) {
            name = name.substring(0, name.lastIndexOf(removeSuffix));
        }
        if (!camelCaseToUnderscore) {
            return prefix.append(name).append(suffix).toString();
        } else {
            for (int i = 0; i < name.length(); i++) {
                if (i > 0 && CharUtils.isAsciiAlphaUpper(name.charAt(i)) && !CharUtils.isAsciiAlphaUpper(name.charAt(i - 1))) {
                    prefix.append("_");
                }
                prefix.append(name.charAt(i));
            }
            return prefix.append(suffix).toString().toLowerCase();
        }
    }
}
